package com.cypher.encryptionanddecryption.bluetooth;

import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothManager;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanResult;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.os.Handler;
import android.widget.ListView;
import android.widget.Toast;

import com.cypher.encryptionanddecryption.activity.MainActivity;
import com.cypher.encryptionanddecryption.adapter.BluetoothListAdapter;
import com.cypher.encryptionanddecryption.fragment.FloatingActionSearchFragment;

import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 蓝牙通信工具类
 * @author: 古霸天
 * @date: 2020/11/5
 */
public class BluetoothUtilManager{

    /**
     * 扫描的时间为15秒
     */
    private static int SCAN_TIME = 15000;
    /**
     * 返回的唯一标识
     */
    private static final int REQUEST_ENABLE_BT = 0x01;
    /**
     * 是否正在扫描
     */
    private static boolean isScanning = false;
    /**
     * 主线程
     */
    private Activity activity;
    /**
     * 蓝牙适配器
     */
    private BluetoothAdapter adapter;
    private Handler handler;

    private boolean isEnable;

    /**
     * 广播接收器
     */
    private BroadcastReceiver receiver;
    /**
     * 存放蓝牙设备信息的集合
     */
    private List<BluetoothDevice> devices;
    /**
     * 展示到列表的蓝牙信息集合
     */
    private List<Map<String, Object>> displayDevices;

    private BluetoothListAdapter listAdapter;
    private ListView bluetoothList;

    private boolean isSetAdapter = false;
    private FloatingActionSearchFragment searchFragment;

    public BluetoothUtilManager(Activity activity) {
        this.activity = activity;
        devices = new ArrayList<BluetoothDevice>();
        displayDevices = new ArrayList<Map<String, Object>>();
        adapter = getBluetoothAdapter();
        if(adapter == null) {
            Toast.makeText(activity, " ", Toast.LENGTH_LONG).show();
            return;
        }

        handler = new Handler();

        isEnable = isCheckBlueToothAdapterEnable();

        initReceiver();
        scanLeDevice();
    }

    public static void setIsScanning(boolean isScanning) {
        BluetoothUtilManager.isScanning = isScanning;
    }
    public Activity getActivity() {
        return activity;
    }
    public void setActivity(Activity activity) {
        this.activity = activity;
    }
    public Handler getHandler() {
        return handler;
    }
    public void setHandler(Handler handler) {
        this.handler = handler;
    }

    public List<Map<String, Object>> getDisplayDevices() {
        return displayDevices;
    }
    public void setBluetoothList(ListView bluetoothList) {
        this.bluetoothList = bluetoothList;
    }
    public BluetoothListAdapter getListAdapter() {
        return listAdapter;
    }
    public void setListAdapter(BluetoothListAdapter listAdapter) {
        this.listAdapter = listAdapter;
    }
    public void setEnable(boolean enable) {
        isEnable = enable;
    }

    /**
     * 获取蓝牙适配器
     * @return
     */
    public BluetoothAdapter getBluetoothAdapter() {
        BluetoothManager bluetoothManager = (BluetoothManager) activity.getSystemService(Context.BLUETOOTH_SERVICE);
        return bluetoothManager.getAdapter();
    }

    /**
     * 校验蓝牙是否开启，未开启则开启蓝牙
     * @return
     */
    public boolean isCheckBlueToothAdapterEnable() {
        if(adapter.isEnabled()) {
            return true;
        }
        if(!adapter.isEnabled()) {
            Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            activity.startActivityForResult(intent, REQUEST_ENABLE_BT);
            return true;
        }
        Toast.makeText(activity, "该设备不支持开启蓝牙", Toast.LENGTH_LONG).show();
        return false;
    }

    /**
     * 注册蓝牙广播接受者
     */
    public void initReceiver() {
        IntentFilter intentFilter = new IntentFilter();
        // 蓝牙 打开、关闭 监听
        intentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
        // 监听网络连接
        intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
        receiver = new ExpandBroadcastReceiver(activity, this);
        activity.registerReceiver(receiver, intentFilter);
    }

    /**
     * 扫描设备
     */
    public void scanLeDevice() {
        if (!isEnable) { // 如果蓝牙未打开先暂停0.1秒  保证蓝牙打开后再扫描
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        if(isEnable) {
            clearDeviceList();
            Runnable runnable = () -> {
                stopScanBluetoothDevice();
            };
            handler.postDelayed(runnable, SCAN_TIME);

            isScanning = true;
            adapter.getBluetoothLeScanner().startScan(mScanCallback);
        }
    }

    /**
     * 开启扫描蓝牙设备
     * @return
     */
    public void startScanBluetoothDevice() {

        // 如果程序正在扫描蓝牙，则新触发的命令是停止扫描蓝牙
        if (isScanning)  {
            // 清理掉之前的子线程
            handler.removeCallbacksAndMessages(null);
            stopScanBluetoothDevice();
            return;
        }

        if (null == adapter) {
            Toast.makeText(activity, "该设备不支持开启蓝牙", Toast.LENGTH_LONG).show();
            return;
        }
        if (!isEnable) {
            Toast.makeText(activity, "请先开启蓝牙后再执行扫描操作", Toast.LENGTH_LONG).show();
            isCheckBlueToothAdapterEnable();
            return;
        }

        // 执行停止蓝牙扫描任务
        Runnable runnable = () -> {
            stopScanBluetoothDevice();
        };

        clearDeviceList();

        handler.postDelayed(runnable, SCAN_TIME);
        isScanning = true;

        adapter.getBluetoothLeScanner().startScan(mScanCallback);
    }

    /**
     * 停止扫描
     */
    public void stopScanBluetoothDevice() {
        if(isScanning) {
            if (searchFragment == null) {
                searchFragment = ((MainActivity)activity).getFloatingActionSearchFragment();
            }
            if (searchFragment != null) searchFragment.clearBtnAnimation();
            isScanning = false;
            adapter.getBluetoothLeScanner().stopScan(mScanCallback);
        }
    }

    /**
     * 5.0 后扫描回调函数
     */
    private ScanCallback mScanCallback = new ScanCallback() {
        @Override
        public void onScanResult(int callbackType, ScanResult result) {
            super.onScanResult(callbackType, result);
            BluetoothDevice device = result.getDevice();
            if (device != null && !devices.contains(device)) {
                if (!StringUtils.isEmpty(device.getName())) {
                    // 向集合加入新接收的设备
                    devices.add(device);
                    // 更新列表页面
                    addList(device);
                }
            }
        }
    };

    /**
     * 向列表添加扫描到的蓝牙信息
     * @param device
     */
    public void addList(BluetoothDevice device) {
        if(listAdapter != null && bluetoothList != null) {
            String deviceName = StringUtils.isEmpty(device.getName()) ? "未知设备" : device.getName();
            Map<String, Object> deviceMap = new HashMap<String, Object>();
            deviceMap.put("name", deviceName);
            deviceMap.put("address", device.getAddress());
            listAdapter.getDevices().add(deviceMap);
            listAdapter.notifyDataSetChanged();
            // 保证只设置一次适配器
            if (!isSetAdapter) {
                bluetoothList.setAdapter(listAdapter);
                isSetAdapter = true;
            }
        }
    }

    /**
     * 清理蓝牙列表数据
     */
    public void clearDeviceList() {
        if (devices.size() > 0) {
            devices.clear();
            displayDevices.clear();
            listAdapter.setDevices(displayDevices);
            listAdapter.notifyDataSetChanged();
            // 保证只设置一次适配器
            if (!isSetAdapter) {
                bluetoothList.setAdapter(listAdapter);
                isSetAdapter = true;
            }
        }
    }

    public List<BluetoothDevice> getDevices() {
        return devices;
    }

    /**
     * 注销广播
     */
    public void destroyReceiver() {
        activity.unregisterReceiver(receiver);
    }

    public void destroyThis() {
        try {
            // 调用垃圾回收
            this.finalize();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
    }
}
